package com.cms.manage.util;

import org.apache.commons.lang3.StringUtils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author yinrenjie
 * @date 2019-05-13 11:24
 * @description
 */
public class BeanUtil {
	

	 public static <T> List<Map<String, Object>> listObjectToListMap(List<T> a) throws Exception {
	        if (a == null) {
	            return null;
	        }
	        String  dateFormat = "yyyy-MM-dd HH:mm:ss";
	        List<Map<String, Object>> res =new ArrayList<>();
	        for (int i = 0; i < a.size(); i++) {
	        	 Map<String, Object> map = new TreeMap<String, Object>();
	        	Field[] declaredFields = a.get(i).getClass().getDeclaredFields();
	        	 for (Field field : declaredFields) {
	 	            field.setAccessible(true);
	 	            Object o = field.get(a.get(i));
	 	            if (null == o) {
	 	                map.put(field.getName(), null);
	 	            } else if (o instanceof String) {
	 	                map.put(field.getName(), (String) o);
	 	            } else if (o instanceof Date) {
	 	                map.put(field.getName(), DateUtil.getString(((Date) o), dateFormat));
	 	            } else if (o instanceof Long) {
	 	                map.put(field.getName(), ((Long) o).toString());
	 	            } else if (o instanceof Integer) {
	 	                map.put(field.getName(), ((Integer) o).toString());
	 	            } else {
	 	                map.put(field.getName(), o.toString());
	 	            }	 	           	           
	 	        }
	        	 res.add(map);
			}    
	        return res;
	    }
	
	
	
	
    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }

        Map<String, Object> map = new TreeMap<String, Object>();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }

        return map;
    }

    public static Map<String, String> objectToMapStringString(Object obj, String dateFormat) throws Exception {
        if (obj == null) {
            return null;
        }

        Map<String, String> map = new TreeMap<String, String>();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object o = field.get(obj);
            if (null == o) {
                map.put(field.getName(), null);
            } else if (o instanceof String) {
                map.put(field.getName(), (String) o);
            } else if (o instanceof Date) {
                map.put(field.getName(), DateUtil.getString(((Date) o), dateFormat));
            } else if (o instanceof Long) {
                map.put(field.getName(), ((Long) o).toString());
            } else if (o instanceof Integer) {
                map.put(field.getName(), ((Integer) o).toString());
            } else {
                map.put(field.getName(), o.toString());
            }
        }

        return map;
    }

    public static Map<String, String> objectToMapStringString_NullAsEmptyString(Object obj, String dateFormat) throws Exception {
        if (obj == null) {
            return null;
        }

        Map<String, String> map = new TreeMap<String, String>();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object o = field.get(obj);
            if (null == o) {
                map.put(field.getName(), "");
            } else if (o instanceof String) {
                map.put(field.getName(), (String) o);
            } else if (o instanceof Date) {
                map.put(field.getName(), DateUtil.getString(((Date) o), dateFormat));
            } else if (o instanceof Long) {
                map.put(field.getName(), ((Long) o).toString());
            } else if (o instanceof Integer) {
                map.put(field.getName(), ((Integer) o).toString());
            } else {
                map.put(field.getName(), o.toString());
            }
        }

        return map;
    }

    /**
     * @param obj
     * @param fields     用英文逗号分隔
     * @param dateFormat
     * @return
     * @throws Exception
     */
    public static Map<String, String> objectToMapStringString(Object obj, String stampFields, String dateFormat) throws Exception {
        if (obj == null) {
            return null;
        }
        if (StringUtils.isNotBlank(stampFields)) {
            stampFields = "," + stampFields + ",";
        } else {
            stampFields = "";
        }

        Map<String, String> map = new TreeMap<String, String>();

        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object o = field.get(obj);
            if (null == o) {
                map.put(field.getName(), null);
            } else if (o instanceof String) {
                map.put(field.getName(), (String) o);
            } else if (o instanceof Date) {
                map.put(field.getName(), DateUtil.getString(((Date) o), dateFormat));
            } else if (o instanceof Long) {
                map.put(field.getName(), ((Long) o).toString());
            } else if (o instanceof Integer) {
                map.put(field.getName(), ((Integer) o).toString());
            } else {
                map.put(field.getName(), o.toString());
            }

            if (stampFields.contains("," + field.getName() + ",")) {
                if (o instanceof Long) {
                    map.put(field.getName(), DateUtil.stampToString((Long) o, dateFormat));
                } else if (o instanceof Integer) {
                    map.put(field.getName(), DateUtil.stampToString((Integer) o, dateFormat));
                }
            }
        }

        return map;
    }

    public static <T> T map2bean(Map<String, Object> map, Class<T> clz) throws Exception {
        //创建一个需要转换为的类型的对象
        T obj = clz.newInstance();
        //从Map中获取和属性名称一样的值，把值设置给对象(setter方法)

        //得到属性的描述器
        BeanInfo b = Introspector.getBeanInfo(clz, Object.class);
        PropertyDescriptor[] pds = b.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            //得到属性的setter方法
            Method setter = pd.getWriteMethod();
            //得到key名字和属性名字相同的value设置给属性
            setter.invoke(obj, map.get(pd.getName()));
        }
        return obj;
    }
}
